home *** CD-ROM | disk | FTP | other *** search
/ PCMania 29 / PCMania CD29.iso / pcmania / juego29 / showega.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-05  |  9.5 KB  |  240 lines

  1. /***************************************************************************/
  2. /*         VISUALIZADOR de PANTALLAS .PCX de 640x480 de 16 colores         */
  3. /*                                                                         */
  4. /*      por: José Antonio Acedo Martín-Grande, miembro de "GOLDY GAMES"    */
  5. /*                                                                         */
  6. /*                     TEL: 6 11 72 71 (MADRID pref. 91)                   */
  7. /***************************************************************************/
  8.  
  9. #include <dos.h>                /*  cabeceras que hacen que se incluyan    */
  10. #include <alloc.h>
  11. #include <conio.h>              /*  durante el proceso de compilado        */
  12. #include <stdio.h>              /*  las funciones que el programa utilize  */
  13. #include <stdlib.h>
  14.  
  15. /******************************* DEFINICIONES ******************************/
  16.  
  17. #define ALFANUMERICO  3         /*  el compilador cambia la palabra por    */
  18. #define GRAFICO      18         /*  su número en el proceso de compilación */
  19.  
  20. /*********************** DECLARACIONES DE FUNCIONES ************************/
  21.  
  22. void asigna_modo_video(char);   /*  definición del tipo de funciones que   */
  23. void asigna_memoria(void);      /*  se usarán en el programa. Se indica el */
  24. void libera_memoria(void);      /*  tipo de dato que devuelven y el tipo   */
  25. void lee_dibujo(void);          /*  de dato/s que necesitan que se les     */
  26. void comprueba_dibujo(void);    /*  pase para funcionar.                   */
  27. void prepara_pantalla(void);
  28. void descomprime_dibujo(void);
  29. void asigna_rgb(void);
  30. void VUELCA_PANTALLA(unsigned char *);
  31.  
  32. /*************************** VARIABLES GLOBALES ****************************/
  33.  
  34. unsigned char *dir_planos;
  35. unsigned char *dir_dibujo;
  36.      char  dibujo[80];
  37.      char  bits_pixel;
  38.      char  num_planos;
  39.      int   colores[16] = { 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63 };
  40.      int   ancho;
  41.      int   alto;
  42.      int   tecla;
  43.      FILE *handle_dibujo;
  44.  
  45. /************************** COMIENZO DEL LISTADO ***************************/
  46.  
  47. void main(void)
  48. /***************************************************************************/
  49. /*      Este es el núcleo del programa. Desde aquí se llama a todas las    */
  50. /*  funciones. Primero se asigna la dirección de comienzo de la zona de    */
  51. /*  pantalla a "dir_pantalla". Seguidamente se dibuja en la pantalla de    */
  52. /*  texto los mensajes y cabeceras para que quede bonita.                  */
  53. /*      NOTA: Las funciones que se han utilizado para presentar texto en   */
  54. /*  color pueden no ser compatibles con tu compilador, si te dan problemas */
  55. /*  omite la función: "dibuja_presentacion()" o intenta sustituir estas    */
  56. /*  funciones por su equivalente en tu compilador.                         */
  57. /*      Seguidamente la función: "gets()" espera a la entrada del nombre   */
  58. /*  del fichero desde el teclado. Hecho esto se reserva memoria para       */
  59. /*  cargar el dibujo solicitado mediante la función: "asigna_memoria()".   */
  60. /*  Entonces la función: "lee_dibujo()" lo carga en memoria. La función:   */
  61. /*  "comprueba_dibujo()" se encarga de comprobar que el dibujo tenga el    */
  62. /*  formato solicitado y no exceda en dimensiones. Si todo es correcto se  */
  63. /*  asignará el modo de vídeo VGA mediante la función:"asigna_modo_video()"*/
  64. /*  y se descomprimirá el dibujo con la función: "descomprime_dibujo()",   */
  65. /*  a la vez que se visualiza en pantalla.                                 */
  66. /*      El dibujo permanecerá en pantalla hasta que pulsemos una tecla.    */
  67. /*  Entonces se reestablecerá el modo de vídeo alfanumérico y se devolverá */
  68. /*  al sistema operativo la memoria que fue asignada con la función:       */
  69. /*  "libera_memoria()", y el programa devolverá el control al DOS.         */
  70. /***************************************************************************/
  71. {
  72.         prepara_pantalla();                   /* prepara la pantalla       */
  73.         gotoxy(14,7);                         /* coloca el cursor          */
  74.         textcolor(LIGHTGREEN);                /* pone tinta a verde brill. */
  75.         cprintf("Introduce el nombre de un fichero .PCX y pulsa ENTER:\n");
  76.         gotoxy(34,19);                        /* coloca el cursor          */
  77.         gets(dibujo);                         /* pide el nombre del dibujo */
  78.         asigna_memoria();                     /* reserva memoria al dibujo */
  79.         lee_dibujo();                         /* lee el dibujo del disco   */
  80.         comprueba_dibujo();                   /* ve si formato es adecuado */
  81.         asigna_modo_video(GRAFICO);           /* activa el modo gráfico    */
  82.         descomprime_dibujo();                 /* descomprime el dibujo     */
  83.         VUELCA_PANTALLA(dir_planos);          /* visualiza el dibujo       */
  84.         tecla=getch();                        /* espera hasta pulse tecla  */
  85.         asigna_modo_video(ALFANUMERICO);      /* activa modo alfanumérico  */
  86.         libera_memoria();                     /* devuelve la memoria al DOS*/
  87. }                                             /* vuelve al DOS             */
  88.  
  89. void prepara_pantalla(void)
  90. {
  91.         int x;
  92.  
  93.         textbackground(BLUE);
  94.         clrscr();
  95.         gotoxy(12,3);
  96.         textcolor(WHITE);
  97.     cprintf("VISUALIZADOR DE PANTALLAS .PCX DE 640 X 480 DE 16 COLORES");
  98.         gotoxy(11,5);
  99.         textcolor(YELLOW);
  100.         cprintf("╔══════════════════════════════════════════════════════════╗");
  101.         for(x=6; x<21; ++x) {
  102.           gotoxy(11,x); cprintf("║"); gotoxy(70,x); cprintf("║");
  103.         }
  104.         gotoxy(11,x);
  105.         cprintf("╚══════════════════════════════════════════════════════════╝");
  106.         textcolor(LIGHTCYAN);
  107.     gotoxy(2,25); cprintf("GOLDY GAMES 1995");
  108.         gotoxy(48,25); cprintf("JOSE ANTONIO ACEDO MARTIN-GRANDE");
  109. }
  110.  
  111. void asigna_modo_video(char modo)      /* asigna el modo de vídeo indicado */
  112. {                                      /* en la variable "modo"            */
  113.         union REGS r;
  114.  
  115.         r.h.al = modo;
  116.         r.h.ah = 0;
  117.         int86(16, &r, &r);
  118. }
  119.  
  120. void asigna_memoria(void)         /* reserva memoria para cargar el dibujo */
  121. {
  122.     if((dir_dibujo=(unsigned char *)farmalloc(153600))==NULL) {
  123.       asigna_modo_video(ALFANUMERICO);
  124.       printf("No hay suficiente memoria. Libera programas residentes.");
  125.       exit(1);
  126.     }
  127.     if((dir_planos=(unsigned char *)farmalloc(153600))==NULL) {
  128.           asigna_modo_video(ALFANUMERICO);
  129.           printf("No hay suficiente memoria. Libera programas residentes.");
  130.           exit(1);
  131.         }
  132. }
  133.  
  134. void libera_memoria(void)             /* libera la memoria asignada al DOS */
  135. {
  136.     farfree(dir_dibujo);
  137.     farfree(dir_planos);
  138. }
  139.  
  140. void lee_dibujo(void)
  141. {
  142.     int       *dir_dibu;
  143.     char huge *dir;
  144.  
  145.         if((handle_dibujo=fopen(dibujo, "rb"))==NULL) {
  146.           asigna_modo_video(ALFANUMERICO);
  147.           printf("No se encontró el dibujo solicitado.");
  148.           exit(1);
  149.         }
  150.  
  151.     dir=(char huge *)dir_dibujo;
  152.     while(!feof(handle_dibujo)) { *dir++=getc(handle_dibujo); }
  153.  
  154.         if(fclose(handle_dibujo)!=NULL) {
  155.           asigna_modo_video(ALFANUMERICO);
  156.           printf("No se pudo cerrar el archivo.");
  157.           exit(1);
  158.         }
  159.  
  160.         dir_dibu=(int *)dir_dibujo;
  161.         bits_pixel=*(dir_dibujo+3);
  162.         num_planos=*(dir_dibujo+65);
  163.         ancho=1+(*(dir_dibu+4));
  164.         alto =1+(*(dir_dibu+5));
  165. }
  166.  
  167. void comprueba_dibujo(void)
  168. {
  169.     if(*dir_dibujo!=10) {
  170.           asigna_modo_video(ALFANUMERICO);
  171.           printf("Este fichero no es un dibujo .PCX."); /* comprueba que el */
  172.           exit(1);                                      /* dibujo sea .PCX  */
  173.         }
  174.         if(bits_pixel!=1 || num_planos!=4) {            /* comprueba que el */
  175.           asigna_modo_video(ALFANUMERICO);              /* dibujo tenga 16  */
  176.           printf("El dibujo no tiene 16 colores.");     /* colores          */
  177.           exit(1);
  178.         }
  179.  
  180.     if(ancho>640 || alto>480) {                     /* comp. el tamaño  */
  181.           asigna_modo_video(ALFANUMERICO);
  182.           printf("El dibujo no cabe en la pantalla. Intenta reducirlo.");
  183.           exit(1);
  184.         }
  185. }
  186.  
  187. void descomprime_dibujo(void)
  188. {
  189.     unsigned char huge *dir_lectura;
  190.     unsigned char huge *dir_escritura;
  191.     unsigned char       byte;
  192.          int        columnas, filas, contador;
  193.  
  194.     dir_lectura  =dir_dibujo+128;       /* inicio del dibujo comprimido */
  195.     dir_escritura=dir_planos;
  196.  
  197.     for(filas=alto; filas>0; filas--) {
  198.       columnas=ancho/2;
  199.       while(columnas>0) {
  200.         byte=*dir_lectura++;
  201.         if(byte<=192) { *dir_escritura++=byte; columnas--; }
  202.         else {
  203.           contador=byte&0x3F; byte=*dir_lectura++;
  204.           for(; contador>0; contador--) {
  205.         *dir_escritura++=byte; columnas--;
  206.           }
  207.         }
  208.       }
  209.     }
  210.     asigna_rgb();
  211. }
  212.  
  213. void asigna_rgb(void)
  214. {
  215.     struct   SREGS  seg;
  216.     union     REGS  ent, sal;
  217.           int   num_color, n;
  218.     long      int   dir;
  219.     unsigned  char *dir_col;
  220.  
  221.     dir_col=dir_dibujo+16;                    /* divide entre 4 */
  222.     for(n=16*3; n>0; n--) {                   /* los colores    */
  223.       *dir_col=(*dir_col) >> 2; dir_col++;
  224.         }
  225.  
  226.     dir   =(long)(dir_dibujo+16);             /* obtiene el segmento     */
  227.     seg.es=(int) (dir >> 16);                 /* donde estan los colores */
  228.  
  229.     for(n=0; n<16; n++) {
  230.       num_color=colores[n];
  231.       ent.h.al = 18;
  232.       ent.h.ah = 16;
  233.       ent.x.bx = num_color;
  234.       ent.x.cx =  1;
  235.       ent.x.dx = (int)dir;            /* offset de los colores            */
  236.       int86x(0x10, &ent, &sal, &seg); /* función para asignar los colores */
  237.       dir+=3;
  238.     }
  239. }
  240.